package com.dplus.common.annomapper;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.mapping.StatementType;
import org.springframework.transaction.annotation.Transactional;

/**
 * 注：本类所执行sql时的封装建议安全sql占位如#{pwd}，也可以非占位，但自己要处理好，详见如下解释
 *BaseMapperAnnotation基接口
 * @param <T> 处理的POJO对象
 *   公共方法使用注解实现，较简便
 *   * 为处理sql安全和严谨
 * 1、建议使用占位符#{key},如使用${key}或使用通用sql语句查询，请自行过滤非法字符
 * 2、建议使用<![CDATA[#{key}]]>,例：select * from sys_user  where email=<![CDATA[#{email}]]> and pwd=<![CDATA[#{pwd}]]>
 * 可以处理“‘”、“""”区分的问题
 * 3、模糊查询请使用自定义动态sql,进行判断和拼接可安全的sql，注意like 取值使用${key}
 * 4、排序字段desc,asc，模糊like,分页标识如 limit,top  均使用${key}
 * 5、此支持最强大的script动态构建sql脚本，如果使用熟练完全可取代xml mapping映射的方法
 */
public interface BaseMapperAnnotation{
	//常用泛型的注解功能
	@Select("select  *  from  ${tableName}")
	public List<Map> findAll(@Param("tableName")String tableName);
	
	@Select("select * from ${tableName} where id=#{id}")
	public Map findById(@Param("tableName")String tableName,@Param("id")String id );
	
	@Transactional
	@Delete("delete from ${tableName} where id=#{id}")
	public int deleteObject(@Param("tableName")String tableName,@Param("id")String id );
	
	//根据sql方式的注解功能
	@Transactional
	@Insert("${sql}")
	public int insertBySqlObject(@Param("sql")String  sql);
	
	@Transactional
	@Update("${sql}")
	public int updateBySqlObject(@Param("sql")String  sql);
	
	@Transactional
	@Delete("${sql}")
	public int deleteBySqlObject(@Param("sql")String  sql);
	
	/**
	 *  * 根据自己写的sql自行处理,及占位符，可支持模糊查询或多表，不固定动态sql条件。
	 * 例sql：   
          SELECT * FROM  sys_user WHERE id=#{id} and name=#{name}
         pojo：key id,name
	* @Description: TODO(描述) 
	* @param  设定
	* @author 作者 jacking 
	* @date 2017-6-16 上午9:42:57 
	* @return
	 */
	@Select("${sql}")
	public List<Map> findBySqlMore(@Param("sql")String  sql,@Param("pojo")Map data);
	/**
	 根据自己写的sql自行处理,及占位符，可支持模糊查询或多表，不固定动态sql条件。
	 * 例sql： 
                 SELECT * FROM  sys_user WHERE id=#{pojo.id} and name=#{pojo.name} 
       pojo：key id,name
	 * @Description: TODO(描述) 
	 * @param  设定
	 * @author 作者 jacking 
	 * @date 2017-6-16 上午9:38:48 
	 * @return
	 */
	@Select("${sql}")
	public Map findBySqlUnique(@Param("sql")String sql,@Param("pojo")Map data);
 /**
  	  **l例： select * from sys_user where 1=1 <if test=\"pojo.id != null and id!=''\"  > and id=#{pojo.id}  </if>
 * @Description: TODO(描述) 
 * @param  设定
 * @author 作者 jacking 
 * @date 2017-6-16 上午11:12:48 
 * @return
  */
	@Select("<script>${scriptSql}</script>")
	public List<Map> findByScriptSqlMore(@Param("scriptSql")String  scriptSql,@Param("pojo")Map data);
	 /**
	  **l例： select * from sys_user where 1=1 <if test=\"pojo.id != null and id!=''\"  > and id=#{pojo.id}  </if>
	 * @Description: TODO(描述) 
	 * @param  设定
	 * @author 作者 jacking 
	 * @date 2017-6-16 上午11:12:48 
	 * @return
	  */
	@Select("<script>${scriptSql}</script>")
	public Map findByScriptSqlUnique(@Param("scriptSql")String scriptSql,@Param("pojo")Map data);
	@Select("<script>"
	   +"select * from sys_user where 1=1 <if test=\"id != null and id!=''\"  > and id=#{id}  </if>" +
//  +"select * from sys_user where 1=1 <if test=\"#{id} != null and #{id}!=''\"  > and id=#{id}  </if>" +
	   " </script>")
	public List<Map> findTestByScript(@Param("id")String id);
	/**
   delete from sys_user where pojo.id='784972358981328902'
	* @Description: TODO(描述) 
	* @param  设定
	* @author 作者 jacking 
	* @date 2017-6-16 上午11:21:55 
	* @return
	 */
	@Transactional
	@Update("<script>${scriptSql}</script>")
	public int excuteByScriptSql(@Param("scriptSql")String  scriptSql,@Param("pojo")Map data);
	/**
	  delete from sys_user where pojo.id='784972358981328902'
	* @Description: TODO(描述) 
	* @param  设定
	* @author 作者 jacking 
	* @date 2017-6-16 上午11:21:42 
	* @return
	 */
	@Transactional
	@Update("${sql}")
	public int excuteBySql(@Param("sql")String  sql,@Param("pojo")Map data);
	@Transactional
	/*@Update("<script>"
	   +"delete from sys_user where id='784972358981328903'" +
//  +"select * from sys_user where 1=1 <if test=\"#{id} != null and #{id}!=''\"  > and id=#{id}  </if>" +
	   " </script>")*/
	@Update("${sql}")
	public int excuteBySqlTest(@Param("sql")String  sql);
	@Select("select 123456")
	public String findTest();
	/**
	 * 调用存储过程,return Map
	 * callsql:
	 * 例：@Select("call  procedureName()")
	 * call procedureName(#{pojo.totalNum,jdbcType=INTEGER,mode=OUT},#{pojo.tableName,jdbcType=STRING,mode=IN},#{pojo.conditions,jdbcType=STRING,mode=IN})
	 */
	@Select("${callSql}")
	@Options(statementType= StatementType.CALLABLE )
	public Map findByCallSql2Map(@Param("callSql")String  callSql,@Param("pojo")Map data);
	/**
	 * 调用存储过程,return List
	 * callsql:
	 * 例：@Select("call  procedureName()")
	 * call procedureName(#{pojo.totalNum,jdbcType=INTEGER,mode=OUT},#{pojo.tableName,jdbcType=STRING,mode=IN},#{pojo.conditions,jdbcType=STRING,mode=IN})
	 */
	@Select("${callSql}")
	@Options(statementType= StatementType.CALLABLE )
	public List findByCallSql2List(@Param("callSql")String  callSql,@Param("pojo")Map data);
	/**
	 * 调用存储过程
	  * callsql:
	 * 例：@Update("call  procedureName()")
	 * call procedureName(#{pojo.totalNum,jdbcType=INTEGER,mode=OUT},#{pojo.tableName,jdbcType=STRING,mode=IN},#{pojo.conditions,jdbcType=STRING,mode=IN})
	 */
	@Update("${callSql}")
	@Options(statementType= StatementType.CALLABLE )
	public int excuteByCallSql(@Param("callSql")String  callSql,@Param("pojo")Map data);
}
